import { Injectable } from '@nestjs/common';
import * as fs from 'fs';
import * as path from 'path';
import * as PDFParser from 'pdf2json';
import * as Config from './app.config';
import { join } from 'path';
import crypto = require('crypto');
import AdmZip = require('adm-zip');
import fse = require('fs-extra')
import randomstring = require("randomstring");
import { RSA_NO_PADDING } from 'constants';
/** Flat node with expandable and level information */
export class DynamicFlatNode {
  constructor(
    public name: string,
    public fileKey: string,
    public level = 0,
    public expandable = false,
    public isLoading = false,
    public parent: string
  ) { }
}
export class FileExtInfo {
  public key: string;
  public fileName: string;
  public fileDate: string;
  public fileKeyword: string;//关键字
  public fileNo: string;//文号
  public fileJg: string;//机构
  public fileYwlx: string;//业务类型
  constructor() { }
}
export class IndexFile {
  constructor() { }
  public version: string = '1.0.0';
  public adminpass: string = "yes123456";
  public userpass: string = "qaz123";
  public nodename?: string;
  public filesExtInfoMap: Map<string, FileExtInfo> = new Map<string, FileExtInfo>();
  toJson() {
    if (this.nodename) {
      return JSON.stringify({
        version: this.version,
        adminpass: this.adminpass,
        userpass: this.userpass,
        nodename: this.nodename,
        indexMap: Array.from(this.filesExtInfoMap.entries()),
      });
    } else {
      return JSON.stringify({
        version: this.version,
        adminpass: this.adminpass,
        userpass: this.userpass,
        indexMap: Array.from(this.filesExtInfoMap.entries()),
      });
    }

  }

  fromJson(jsonStr: string): IndexFile {
    //console.log('fromJson', jsonStr);
    let json = JSON.parse(jsonStr);
    this.version = json.version;
    this.adminpass = json.adminpass;
    this.userpass = json.userpass;
    if (json.nodename) {
      this.nodename = json.nodename;
    }
    console.log('fromJson', json.indexMap);
    this.filesExtInfoMap = new Map<string, FileExtInfo>(json.indexMap);
    return this;
  }
  getExtinfo(key: string): FileExtInfo {
    //console.log(key, this.indexMap);
    return this.filesExtInfoMap.get(key);
  }
}
@Injectable()
export class AppService {
  rootpath: string = Config.dataPath;
  filespath: string = join(Config.dataPath, "files");
  nodepath: string = join(Config.dataPath, "node");
  keypath: string = join(Config.dataPath, "key");
  indexFile: IndexFile;
  currusername: string;
  constructor() {
    console.log('AppService constructor');
    this.indexFile = this.loadIndexFile();
    console.log(this.indexFile);
  }

  private loadIndexFile(): IndexFile {
    let data: Buffer, indexFile: IndexFile;
    indexFile = new IndexFile();
    try {
      data = fs.readFileSync(path.join(this.rootpath, 'index.json'));
      //fileExtinfo = <FileExtinfo>JSON.parse(data.toString());
      indexFile = indexFile.fromJson(data.toString());
    } catch (e) {
      console.log(e.Error);
    }
    return indexFile;
  }
  private saveIndexFile(): IndexFile {
    //console.log('================saveIndexFile');
    //console.log(this.indexFile.toJson());
    fs.writeFileSync(
      path.join(this.rootpath, 'index.json'),
      this.indexFile.toJson(),
    );
    return this.indexFile;
  }
  ////////////
  login(param: any): Object {
    let loginok = false;
    if (param.username == "admin") {
      if (param.password == this.indexFile.adminpass) {
        loginok = true;
      }
    } else {
      if (param.password == this.indexFile.userpass) {
        loginok = true;
      }
    }
    if (loginok) this.currusername = param.username;
    return { ok: loginok, user: param };
  }
  saveExtinfo(param: any): string {
    console.log('service saveExtinfo', param);
    //let indexMap: Map<string, ExtInfo> = new Map<string, ExtInfo>();
    this.indexFile.filesExtInfoMap.set(
      param.extinfo.key,
      param.extinfo
    );
    this.saveIndexFile();
    return JSON.stringify({ ok: true });
  }
  getExtinfo(param: any): string {
    //let key = path.join(param.node.parent, param.node.fileName);
    let extinfo = this.indexFile.getExtinfo(param.fileKey);
    console.log(param.fileKey, extinfo, this.indexFile.filesExtInfoMap);
    return JSON.stringify({
      ok: true,
      data: extinfo
    });
  }
  searchFile(param: any): string {
    let data: Array<Object> = new Array<Object>();
    console.log("searchFile param", param);
    for (let [key, extInfo] of this.indexFile.filesExtInfoMap) {
      //console.log(key, JSON.stringify(extInfo).indexOf(param.txt)); 
      if (JSON.stringify(extInfo).indexOf(param.txt) >= 0) {//这样查找可以吧，速度肯定够快
        data.push({ key: key, name: extInfo.fileName, extinfo: extInfo });
      } else {//如果在文件的扩展信息中没有找到，再搜索一下文件的文本格式内容
        let filepath = path.join(this.filespath, key + ".txt");
        console.log("查找文件文本格式", filepath);
        try {
          let filetxt = fs.readFileSync(filepath).toString();
          //fileExtinfo = <FileExtinfo>JSON.parse(data.toString());
          //console.log(filetxt,filetxt.indexOf(param.txt));
          if (filetxt.indexOf(param.txt) >= 0) {
            data.push({ key: key, name: extInfo.fileName, extinfo: extInfo });
          }
        } catch (e) {
          console.log(e.Error);
        }
      }

    }
    return JSON.stringify({
      ok: true,
      data: data,
    });
  }
  //根据文件扩展信息精确查找文件
  searhFileFromExtinfo(param: any): string {
    let data: Array<Object> = new Array<Object>();
    //console.log("searhFileFromExtinfo param", param, param.fileDate, param.fileDate == null, param.fileDate >= "2020-06-10");

    for (let [key, extinfo] of this.indexFile.filesExtInfoMap) {
      //console.log(extinfo.fileDate, param.fileDate1, extinfo.fileDate.localeCompare(param.fileDate1));
      // console.log(extinfo.fileName,extinfo.fileNo,param.fileYwlx);

      // console.log((param.fileName == null || (extinfo.fileName && extinfo.fileName.indexOf(param.fileName) >= 0)));
      // console.log((param.fileKeyword == null || (extinfo.fileKeyword && extinfo.fileKeyword.indexOf(param.fileKeyword) >= 0)));
      // console.log((param.fileNo == null || (extinfo.fileNo && extinfo.fileNo.indexOf(param.fileNo) >= 0)));
      // console.log((param.fileJg == null || (extinfo.fileJg && extinfo.fileJg.indexOf(param.fileJg) >= 0)));
      // console.log((param.fileYwlx == null || (extinfo.fileYwlx && extinfo.fileYwlx.indexOf(param.fileYwlx) >= 0)));
      // console.log((param.fileDate == null || (extinfo.fileDate && extinfo.fileDate.localeCompare(param.fileDate) == 0)));

      // let tmp = (param.fileName == null || (extinfo.fileName && extinfo.fileName.indexOf(param.fileName) >= 0)) &&
      // (param.fileKeyword == null || (extinfo.fileKeyword && extinfo.fileKeyword.indexOf(param.fileKeyword) >= 0)) &&
      // (param.fileNo == null || (extinfo.fileNo && extinfo.fileNo.indexOf(param.fileNo) >= 0)) &&
      // (param.fileJg == null || (extinfo.fileJg && extinfo.fileJg.indexOf(param.fileJg) >= 0)) &&
      // (param.fileYwlx == null || (extinfo.fileYwlx && extinfo.fileYwlx.indexOf(param.fileYwlx) >= 0)) &&
      // (param.fileDate == null || (extinfo.fileDate && extinfo.fileDate.localeCompare(param.fileDate) == 0));
      // console.log("总结",tmp);

      if ((param.fileName == null || (extinfo.fileName && extinfo.fileName.indexOf(param.fileName) >= 0)) &&
        (param.fileKeyword == null || (extinfo.fileKeyword && extinfo.fileKeyword.indexOf(param.fileKeyword) >= 0)) &&
        (param.fileNo == null || (extinfo.fileNo && extinfo.fileNo.indexOf(param.fileNo) >= 0)) &&
        (param.fileJg == null || (extinfo.fileJg && extinfo.fileJg.indexOf(param.fileJg) >= 0)) &&
        (param.fileYwlx == null || (extinfo.fileYwlx && extinfo.fileYwlx.indexOf(param.fileYwlx) >= 0)) &&
        (param.fileDate == null || (extinfo.fileDate && extinfo.fileDate.localeCompare(param.fileDate) == 0))) {

        data.push({ key: key, name: extinfo.fileName, extinfo: extinfo });
      }
    }
    return JSON.stringify({
      ok: true,
      data: data,
    });
  }
  //////
  getYwlxTree(filekey: string): string {
    console.log('getYwlx', filekey);
    class FoodNode {
      constructor(
        public item: string,
        public checked: boolean,
        public children?: FoodNode[]) {
      }
    }
    function getNodeChildren(nodepath: string): FoodNode[] {
      let nodeArray: FoodNode[] = [];
      var pa = fs.readdirSync(nodepath);
      //console.log(pa,pa.indexOf(filekey)>-1);
      for (let ele of pa) {
        //console.log(path + ele);
        var info = fs.statSync(path.join(nodepath, ele));
        //console.log(info);
        //如果是目录，再对目录中的文件进行遍历
        if (info.isDirectory()) {
          console.log('dir: ' + ele);
          //fs.readDirSync(path + ele);
          nodeArray.push(new FoodNode(ele, fs.existsSync(path.join(nodepath, ele, filekey)), getNodeChildren(path.join(nodepath, ele))));
        }
      }
      return nodeArray;
    }
    let nodeArray: FoodNode[] = [];
    var pa = fs.readdirSync(this.nodepath);

    for (let ele of pa) {
      //console.log(path + ele);
      //if (this.currusername == "admin" || ele.indexOf("我的文件夹") > -1) {
      var info = fs.statSync(path.join(this.nodepath, ele));
      //console.log(info);
      //如果是目录，再对目录中的文件进行遍历
      if (info.isDirectory()) {
        console.log('dir: ' + ele);
        //fs.readDirSync(path + ele);
        nodeArray.push(new FoodNode(ele, fs.existsSync(path.join(this.nodepath, ele, filekey)), getNodeChildren(path.join(this.nodepath, ele))));
      }
      //}
    }
    //return this.dataMap.get(node);
    return JSON.stringify({ ok: true, nodes: nodeArray });

  }

  getChildren(node: DynamicFlatNode): string {
    //node==null 是获得根目录
    console.log('getChildren', node);
    let nodePath: string = this.nodepath;
    let nodeParent: string = '';
    let nodeLevel: number = 0;
    if (node) {
      nodePath = path.join(nodePath, node.parent, node.name);
      nodeParent = path.join(node.parent, node.name);
      nodeLevel = node.level + 1;
    }
    let nodeArray: DynamicFlatNode[] = [];
    var pa = fs.readdirSync(nodePath);
    for (let ele of pa) {
      //console.log(path + ele);
      var info = fs.statSync(path.join(nodePath, ele));
      //console.log(info);
      //如果是目录，再对目录中的文件进行遍历
      if (info.isDirectory()) {
        console.log('dir: ' + ele);
        //fs.readDirSync(path + ele);
        nodeArray.push(new DynamicFlatNode(ele, "", nodeLevel, true, false, nodeParent));
      } else {
        //文件
        console.log("file: " + ele + "  扩展名：", path.extname(ele))
        //if (path.extname(ele).toLowerCase() == ".pdf") {
        let name: string = ele;
        let fileKey = ele;
        let extinfo = this.indexFile.getExtinfo(fileKey);
        console.log("get children exitinfo:", extinfo);
        if (extinfo) {
          name = extinfo.fileName;
          fileKey = extinfo.key;
        }
        nodeArray.push(new DynamicFlatNode(name, fileKey, nodeLevel, false, false, nodeParent));
        //}

      }
    }
    //return this.dataMap.get(node);
    return JSON.stringify({ ok: true, nodes: nodeArray });
  }

  renameNode(node: DynamicFlatNode, name: string): string {//断言node不为空，而且是文件夹
    let currPath = path.join(this.nodepath, node.parent, node.name);
    let curYwlx = path.join(node.parent, node.name);
    let newPath = path.join(this.nodepath, node.parent, name);
    let newYwlx = path.join(node.parent, name);
    try {
      fs.renameSync(currPath, newPath)
      console.log("Successfully renamed the directory.", currPath, newPath);
      this.renameYwlx(curYwlx, newYwlx);
      return JSON.stringify({ ok: true });
    } catch (err) {
      console.log(err)
      return JSON.stringify({ ok: false, message: err });
    }
  }
  addNode(node: DynamicFlatNode, name: string): string {
    let nodepath: string;
    if (node) {
      if (node.expandable) {
        //选中的是个目录，新增加是其子目录
        console.log('选中了node，在此node下创建子目录');
        nodepath = path.join(this.nodepath, node.parent, node.name, name);
      } else {
        //选中的是个文件，新增加作为其同级目录
        nodepath = path.join(this.nodepath, node.parent, name);
      }
    } else {
      console.log('没有选中node，创建一级目录');
      nodepath = path.join(this.nodepath, name);
    }
    if (!fs.existsSync(nodepath)) {
      console.log('文件不存在,现在创建', nodepath);
      //return;
      fs.mkdirSync(nodepath);
    }
    return JSON.stringify({ ok: true });
  }
  private nodeToJson(nodename: string, nodeparent: string): DynamicFlatNode[] {//断言node非空，并且是目录节点 adm zip 可以压缩目录，目录结构转json这个函数没使用到
    console.log('nodeToJson', nodename, nodeparent);
    class TreeNode {
      constructor(
        public name: string,
        public fileKey: string,
        public level = 0,
        public expandable = false,
        public isLoading = false,
        public parent: string,
        public children?: TreeNode[]
      ) { }
    }
    let thisnodePath: string = path.join(this.nodepath, nodeparent, nodename);
    let newnodeParent: string = path.join(nodeparent, nodename);
    let nodeArray: TreeNode[] = [];
    var pa = fs.readdirSync(thisnodePath);
    for (let ele of pa) {
      //console.log(path + ele);
      var info = fs.statSync(path.join(thisnodePath, ele));
      //console.log(info);
      //如果是目录，再对目录中的文件进行遍历
      if (info.isDirectory()) {
        console.log('dir: ' + ele);
        //fs.readDirSync(path + ele);
        nodeArray.push(new TreeNode(ele, "", 0, true, false, newnodeParent, this.nodeToJson(ele, newnodeParent)));
      } else {
        //文件
        console.log("file: " + ele)
        //if (path.extname(ele).toLowerCase() == ".pdf") {
        let name: string;
        let fileKey = ele;
        let extinfo = this.indexFile.getExtinfo(fileKey);
        console.log("get children exitinfo:", extinfo);
        if (extinfo) {
          name = extinfo.fileName;
          fileKey = extinfo.key;
        }
        nodeArray.push(new TreeNode(name, fileKey, 0, false, false, newnodeParent));
        //}
      }
    }
    //return this.dataMap.get(node);
    return nodeArray;

  }
  private parsePathGetRealFile(currpath: string) {
    var pa = fs.readdirSync(currpath);
    for (let ele of pa) {
      let elePath = path.join(currpath, ele);
      var info = fs.statSync(elePath);
      //console.log(info);
      //如果是目录，再对目录中的文件进行遍历
      if (info.isDirectory()) {
        this.parsePathGetRealFile(elePath);
      } else {
        let fileKey = path.basename(elePath);
        let extinfo = this.indexFile.getExtinfo(fileKey);
        console.log("exiinfo", extinfo, fileKey);
        if (extinfo) {
          let fileno = extinfo.fileNo ? "(" + extinfo.fileNo + ")" : "";
          let destFileName = extinfo.fileName + fileno + ".pdf";
          console.log(destFileName);
          fs.copyFileSync(path.join(this.filespath, fileKey + ".pdf"), path.join(currpath, destFileName));
          fs.unlinkSync(elePath);
        }
      }
    }

  }
  //导出人可用的文件包，就是把文件名还原成正常，压缩zip，中文名乱码，所以放弃
  exportFiles(param): string {//node 一定是目录,把node以及包含的文件，压缩成一个zip文件，返回前端下载
    let node: DynamicFlatNode = param.node;
    let toDestPath = path.join(param.toDestPath, node.name);
    let zipfileName: string = node.name + ".zip";
    let nodepath: string;
    nodepath = path.join(this.nodepath, node.parent, node.name);
    let temprootpath = path.join(this.rootpath, "temp");
    try {
      console.log("exportFiles", path.join(this.filespath, zipfileName));
      fse.removeSync(temprootpath);
      fse.copySync(nodepath, temprootpath);
      this.parsePathGetRealFile(temprootpath);
      console.log("toDestPath", toDestPath);
      fse.removeSync(toDestPath);
      fse.copySync(temprootpath, toDestPath);
      // var zip = new AdmZip();
      // zip.addLocalFolder(temprootpath);
      // zip.addFile("测试中文名",Buffer.from("ceshi测试"));
      // zip.writeZip(path.join(this.filespath, "download", zipfileName));
      fse.removeSync(temprootpath);
      return JSON.stringify({ ok: true, zipfileName: zipfileName });
    } catch (e) {
      return JSON.stringify({ ok: false, message: e });
    }

  }
  exportData(node: DynamicFlatNode): string {//node 一定是目录,把node以及包含的文件，压缩成一个zip文件，返回前端下载
    let zipfileName: string = node.name + ".zid";//为了不被轻易打开看内容
    let nodepath: string;
    nodepath = path.join(this.nodepath, node.parent, node.name);
    try {
      console.log("exportData", path.join(this.filespath, zipfileName));
      var zip = new AdmZip();

      zip.addLocalFolder(nodepath, "node");
      var zipEntries = zip.getEntries(); // an array of ZipEntry records
      let files: Array<string> = [];
      for (let zipEntry of zipEntries) {
        if (!zipEntry.isDirectory) {
          console.log("filename:", zipEntry.name);
          let fileinfo = this.indexFile.filesExtInfoMap.get(zipEntry.name);
          if (fileinfo) {//如果该文件fileinfo 为 null，丢失了fileinfo，就不导出了
            files.push(zipEntry.name);
          }
        }
      }
      let indexFile: IndexFile = new IndexFile();
      for (let file of files) {
        let filepath = path.join(this.filespath, file + ".pdf");

        if (fs.existsSync(filepath)) {
          zip.addLocalFile(filepath, "files");
          indexFile.filesExtInfoMap.set(file, this.indexFile.filesExtInfoMap.get(file));
        }
        filepath = path.join(this.filespath, file + ".txt");
        if (fs.existsSync(filepath)) {
          zip.addLocalFile(filepath, "files");
        }

      }
      indexFile.nodename = node.name;
      let indexfilejson = indexFile.toJson();
      //console.log(indexfilejson);
      zip.addFile("nodeindex.json", Buffer.from(indexfilejson));

      zip.writeZip(path.join(this.filespath, "download", zipfileName));
      return JSON.stringify({ ok: true, zipfileName: zipfileName });
    } catch (e) {
      return JSON.stringify({ ok: false, message: e });
    }

  }
  nodeDelFile(param: any): string {
    console.log("nodeDelFile", param);
    try {
      let nodeFilePath = path.join(this.nodepath, param.path, param.filekey);
      console.log(nodeFilePath);
      fs.unlinkSync(nodeFilePath);
      this.delFileYwlx(param.filekey, param.path);
      return JSON.stringify({ ok: true });
    } catch (e) {
      return JSON.stringify({ ok: false, message: e });
    }
  }
  delNode(node: DynamicFlatNode): string {
    let files = [];
    let temppath: string;
    if (node.expandable) {//是目录
      temppath = path.join(this.nodepath, node.parent, node.name);
    } else {//是文件
      temppath = path.join(this.nodepath, node.parent, node.fileKey);
    }
    if (fs.existsSync(temppath)) {
      if (fs.statSync(temppath).isDirectory()) {
        files = fs.readdirSync(temppath);
        for (let file of files) {
          let curPath = path.join(temppath, file);
          if (fs.statSync(curPath).isDirectory()) {
            let curNode = new DynamicFlatNode(file, file, node.level + 1, true, false, path.join(node.parent, node.name));
            this.delNode(curNode); //递归删除文件夹
          } else {
            fs.unlinkSync(curPath); //删除文件
            this.delFileYwlx(file, node.parent);
          }
        }
        fs.rmdirSync(temppath);
      } else {
        fs.unlinkSync(temppath);
        this.delFileYwlx(node.fileKey, node.parent);
      }
      //this.saveIndexFile();
    }
    return JSON.stringify({ ok: true });
  }
  private renameYwlx(curYwlx: string, newYwlx: string) {
    console.log("renameYwlx", curYwlx, newYwlx);
    for (let [key, extinfo] of this.indexFile.filesExtInfoMap) {
      console.log(extinfo.fileYwlx);
      extinfo.fileYwlx = extinfo.fileYwlx.replace(curYwlx, newYwlx);
      console.log(extinfo.fileYwlx);
    }
    this.saveIndexFile();
  }
  private delFileYwlx(fileKey: string, ywlx: string) {//如果业务类型空，说明已经没有业务类型引用该文件，把实体文件删除
    console.log("delFileYwlx", fileKey, ywlx);
    let extinfo = this.indexFile.getExtinfo(fileKey);
    if (extinfo) {
      let ywlxes: Array<string> = extinfo.fileYwlx.split(',');
      var index = ywlxes.indexOf(ywlx);
      if (index !== -1) {
        ywlxes.splice(index, 1);
      }
      console.log(ywlxes.join(","));
      if (ywlxes.length > 0) {
        extinfo.fileYwlx = ywlxes.join(",");
        this.indexFile.filesExtInfoMap.set(fileKey, extinfo);
      } else {//业务类型空了，删除文件  
        console.log("=========================业务类型空了，删除文件")
        this.indexFile.filesExtInfoMap.delete(fileKey);
        try {
          fs.unlinkSync(path.join(this.filespath, fileKey + ".pdf"));
          fs.unlinkSync(path.join(this.filespath, fileKey + ".txt"));
        } catch (e) {
          console.log("删除文件出错了！", e);
        }
      }
      this.saveIndexFile();
    }
  }
  copyfile(param: any): string {//拷贝文件的逻辑，在新的存储结构下，会很简单，如果还需要，再实现
    // let sourceNode = param.sourceNode;
    // let destNode = param.destNode;
    // let sourceFile = path.join(this.rootpath, sourceNode.parent, sourceNode.fileName);
    // let destFile: string, key: string;
    // if (destNode.expandable) {
    //   destFile = path.join(this.rootpath, destNode.parent, destNode.fileName, sourceNode.fileName);
    //   key = path.join(destNode.parent, destNode.fileName, sourceNode.fileName);
    // } else {
    //   destFile = path.join(this.rootpath, destNode.parent, sourceNode.fileName);
    //   key = path.join(destNode.parent, sourceNode.fileName);
    // }
    // console.log("copyFile:", sourceFile, destFile);
    // try {
    //   fs.copyFileSync(sourceFile, destFile);
    //   if (fs.existsSync(sourceFile + ".txt")) {
    //     fs.copyFileSync(sourceFile + ".txt", destFile + ".txt");
    //   }
    //   let sourceKey = path.join(sourceNode.parent, sourceNode.fileName);
    //   let extinfo = this.fileExtinfo.getExtinfo(sourceKey);
    //   console.log(sourceKey, extinfo);
    //   if (extinfo) {
    //     this.fileExtinfo.indexMap.set(key, extinfo);
    //     this.saveIndexFile();
    //   }
    return JSON.stringify({ ok: true });
    // } catch (e) {
    //   console.log(e);
    //   return JSON.stringify({ ok: false });
    // }

  }
  nodeAddFile(param: any): string {
    console.log("nodeAddFile", param);
    try {
      let nodeFilePath = path.join(this.nodepath, param.path, param.filekey);
      console.log(nodeFilePath);
      fs.writeFileSync(nodeFilePath, "Hello World,通过点击checkbox加入,Program design by LJF,QQ:53336158");
      this.addFileYwlx(param.filekey, param.path);
      return JSON.stringify({ ok: true });
    } catch (e) {
      return JSON.stringify({ ok: false, message: e });
    }
  }

  importData(param): string {//param.node 断言是空或者目录节点，为空是增加根目录
    let nodepath: string = this.nodepath;;
    if (param.node) {
      nodepath = path.join(this.nodepath, param.node.parent, param.node.name);
    }
    console.log("importData", param.files[0], nodepath);
    let indexFile: IndexFile;
    try {
      var zip = new AdmZip(param.files[0]);
      let zipfilerootpath = path.join(this.rootpath, "temp");
      zip.extractAllTo(zipfilerootpath);
      if (!fs.existsSync(path.join(zipfilerootpath, "nodeindex.json"))) {
        return JSON.stringify({ ok: false, message: "数据包格式错误！nodeindex.json文件不存在" });
      }
      let data: Buffer;
      indexFile = new IndexFile();
      try {
        data = fs.readFileSync(path.join(zipfilerootpath, "nodeindex.json"));
        indexFile = indexFile.fromJson(data.toString());
        for (let fileinfo of indexFile.filesExtInfoMap.values()) {//业务类型会乱掉，导入和导出，原来所在目录和新导入的目录，情况复杂，导致业务类型难以处理
          console.log("importData", fileinfo);
          if (fileinfo) {//有人导出的数据包，fileinfo是 null
            this.indexFile.filesExtInfoMap.set(fileinfo.key, fileinfo);
          }
        }
        this.saveIndexFile();
        fse.copySync(path.join(zipfilerootpath, "files"), this.filespath);
        //console.log(path.join(zipfilerootpath, "node"), path.join(nodepath, indexFile.nodename));
        fse.copySync(path.join(zipfilerootpath, "node"), path.join(nodepath, indexFile.nodename));

      } catch (e) {
        console.log(e);
        return JSON.stringify({ ok: false, message: "数据包格式错误！indexjson解析失败", error: e });
      }
      fse.removeSync(zipfilerootpath);
      return JSON.stringify({ ok: true, nodename: indexFile.nodename });
    } catch (e) {
      return JSON.stringify({ ok: false, message: e });
    }
  }
  async addfile(param: any): Promise<string> {//文件统一存放files目录中，相同内容的文件只有一份，文件名是文件内容的hash值，可以增加一个nodeaddfile函数，node中的文件，只是一个文件名，无内容，起一个标记作用
    let nodeFilePath: string;
    let fileYwlx: string;
    let okfiles: Array<object> = new Array<object>();
    let errfiles: Array<string> = new Array<string>();
    if (param.node.expandable) {
      nodeFilePath = path.join(this.nodepath, param.node.parent, param.node.name);
      fileYwlx = path.join(param.node.parent, param.node.name);
    } else {
      nodeFilePath = path.join(this.nodepath, param.node.parent);
      fileYwlx = param.node.parent;
    }
    console.log("addfile", param);
    try {
      for (let sourceFile of param.files) {
        let fileName = path.basename(sourceFile);
        let file_buffer = fs.readFileSync(sourceFile);
        let shasum = crypto.createHash('sha256');
        shasum.update(file_buffer);
        const key: string = shasum.digest('hex');//('base64');

        let destTxtFile = path.join(this.filespath, key + '.txt');

        let fileExists = fs.existsSync(destTxtFile);
        let pdf2txtResult: any = { ok: true };
        if (!fileExists) {
          pdf2txtResult = await this.pdf2txt(sourceFile, destTxtFile, file_buffer);
        }

        console.log("99999999999999999", pdf2txtResult);
        if (pdf2txtResult.ok) {
          if (!fileExists) fs.writeFileSync(path.join(this.filespath, key + ".pdf"), file_buffer);
          fs.writeFileSync(path.join(nodeFilePath, key), "Hello World! Program design by LJF,QQ:53336158");
          let fileExtInfo = this.indexFile.getExtinfo(key);
          if (fileExtInfo === undefined) {
            fileExtInfo = new FileExtInfo();
            fileExtInfo.key = key;
            fileExtInfo.fileName = fileName.substring(0, fileName.lastIndexOf("."));
            fileExtInfo.fileYwlx = fileYwlx;
            let pos1 = fileName.lastIndexOf("(");
            if (pos1 < 0) pos1 = fileName.lastIndexOf("（");
            let pos2 = fileName.lastIndexOf(")");
            if (pos2 < 0) pos2 = fileName.lastIndexOf("）");
            if (pos1 > -1 && pos2 > -1) {
              let fileNo = fileName.substring(pos1 + 1, pos2);
              fileExtInfo.fileNo = fileNo;
            }
          } else {
            if (fileExtInfo.fileYwlx.indexOf(fileYwlx) < 0) {
              fileExtInfo.fileYwlx += "," + fileYwlx;
            }
          }
          this.indexFile.filesExtInfoMap.set(key, fileExtInfo);
          okfiles.push({ fileKey: key, fileName: fileExtInfo.fileName });
        } else {//pdf转txt失败，说明pdf文件格式错误
          errfiles.push(fileName);
        }
      }
      console.log('add file finished');
      this.saveIndexFile();
      return JSON.stringify({ ok: true, okfiles: okfiles, errfiles: errfiles });
    } catch (e) {
      return JSON.stringify({ ok: false, message: e });
    }
  }
  private addFileYwlx(fileKey: string, ywlx: string) {
    let fileExtInfo = this.indexFile.getExtinfo(fileKey);
    if (fileExtInfo.fileYwlx.indexOf(ywlx) < 0) {
      fileExtInfo.fileYwlx += "," + ywlx;
      this.indexFile.filesExtInfoMap.set(fileKey, fileExtInfo);
      this.saveIndexFile();
    }
  }

  pdf2txt(sourceFile: string, destFile: string, file_buffer: Buffer) {
    const promise = new Promise((resolve, reject) => {
      let pdfParser = new PDFParser(this, 1);
      pdfParser.on('pdfParser_dataError', errData => {
        console.error(errData.parserError);
        resolve({ ok: false });
      });
      pdfParser.on('pdfParser_dataReady', pdfData => {
        // fs.writeFile("/home/lieefu/angularWork/angular-electron/nsfiles/科技制度//F1040EZ.json",
        //  JSON.stringify(pdfData),err=>console.log(err));
        let data = pdfParser.getRawTextContent();
        fs.writeFile(destFile, data.replace(/[\r\n]/g, ""), err => {
          if (err) {
            console.log(err);
            resolve({ ok: false });
          } else {
            resolve({ ok: true });
            console.log('pdf to txt finished');
          }
        });
      });
      if (file_buffer) {
        console.log("pdf to txt from file_buffer");
        pdfParser.parseBuffer(file_buffer);
      } else {
        pdfParser.loadPDF(sourceFile);
      }
    });
    return promise;
  }
  fileMd5(filepath: string): string {
    let file_buffer = fs.readFileSync(filepath);
    let sum = crypto.createHash('sha256');
    sum.update(file_buffer);
    const hex = sum.digest('hex');
    console.log(hex);
    return hex;
  }
  getRandomInt(max: number): number {
    return Math.floor(Math.random() * Math.floor(max));
  }
  generateKey(username: string, datestr: string) {
    let forest = randomstring.generate(999);
    let sum = crypto.createHash('sha256');
    sum.update(username);
    let usernamemd5 = sum.digest('base64');
    sum = crypto.createHash('sha256');
    sum.update(username);
    let filename = sum.digest("hex") + ".key";

    let datebase64 = this.strtobase64(datestr);
    let key = usernamemd5 + datebase64;
    let pos = this.getRandomInt(999);
    let data = forest.substring(0, pos) + key + forest.substring(pos);
    if (!fs.existsSync(this.keypath)) {
      fs.mkdirSync(this.keypath);
    }
    fs.writeFileSync(path.join(this.keypath, filename), data);
  }
  getKey(username: string): Object {
    let datestr: string = "";
    let sum = crypto.createHash('sha256');
    sum.update(username);
    let usernamemd5 = sum.digest('base64');
    sum = crypto.createHash('sha256');
    sum.update(username);
    let filename = sum.digest("hex") + ".key";

    let data = fs.readFileSync(path.join(this.keypath, filename)).toString();
    let pos = data.indexOf(usernamemd5);
    if (pos > -1) {
      console.log(pos);
      pos = pos + usernamemd5.length;
      console.log(pos);
      let datebase64 = data.substring(pos, pos + this.strtobase64("20201210").length);
      console.log(datebase64);
      datestr = this.base64tostr(datebase64);
      console.log(datestr);
    }
    return { username: username, datestr: datestr };
  }
  getKeyDate(username: string): Date {
    let key: any = this.getKey(username);
    return this.strtodate(key.datestr);
  }
  keyexist(username: string): boolean {
    let sum = crypto.createHash('sha256');
    sum.update(username);
    let filename = sum.digest("hex") + ".key";
    return fs.existsSync(path.join(this.keypath, filename));
  }

  strtobase64(str: string): string {
    return Buffer.from(str).toString('base64')
  }
  base64tostr(base64str: string): string {
    return Buffer.from(base64str, 'base64').toString()
  }
  strtodate(dateString: string): Date {
    const year = +dateString.substr(0, 4);
    const month = +dateString.substr(4, 2) - 1;
    const day = +dateString.substr(6, 2);
    return new Date(year, month, day);
  }
}
